package cn.lingyangwl.agile.auth.controller;

import cn.lingyangwl.agile.auth.model.entity.OAuth2Client;
import cn.lingyangwl.agile.auth.model.rqrs.client.*;
import cn.lingyangwl.agile.auth.service.OAuth2ClientService;
import cn.lingyangwl.agile.ram.ActionType;
import cn.lingyangwl.agile.ram.RamResource;
import cn.lingyangwl.agile.system.SystemApi;
import cn.lingyangwl.framework.core.response.Resp;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * oauth客户端, 只能存在与一个租户下的一个应用下, 统一管理, 否则分配角色会有问题
 *
 * @author shenguangyang
 */
@RequiredArgsConstructor
@Api(tags = "oauth客户端")
@RestController
@RequestMapping("/oauth2/client")
public class OAuth2ClientController {

	private final OAuth2ClientService oauth2ClientService;
	private final SystemApi systemApi;

	/**
	 * 通过client id查询, 只供内部调用
	 */
	@GetMapping("/getByClientId")
	public Resp<OAuth2Client> getByClientId(@RequestParam("clientId") String clientId) {
		return Resp.ok(oauth2ClientService.getByClientId(clientId));
	}

	/**
	 * 分页 oauth客户端
	 */
	@GetMapping("/page")
	@RamResource(action = "auth:authClientDetails:query", name = "查询oauth客户端", type = ActionType.READ)
	public Resp<IPage<OAuthClientResp>> pageClient(@Validated OAuthClientPageReq req) {
		return Resp.ok(oauth2ClientService.pageClient(req));
	}

	@GetMapping("/list")
	@RamResource(action = "auth:authClientDetails:query", name = "查询oauth客户端", type = ActionType.READ)
	public Resp<OAuthClientListResp> listClient(@Validated OAuthClientListReq req) {
		return Resp.ok(oauth2ClientService.listClient(req));
	}

	/**
	 * 通过id查找 oauth客户端
	 */
	@GetMapping("/get")
	@RamResource(action = "auth:authClientDetails:query", name = "查询oauth客户端", type = ActionType.READ)
	public Resp<OAuthClientResp> getClient(@RequestParam(value = "id") Long id) {
		return Resp.ok(oauth2ClientService.getClient(id));
	}

	@GetMapping("/listExtLdpConn")
	@RamResource(action = "auth:authClientDetails:queryExtLdpConn", name = "查询可用的外部身份源", type = ActionType.READ)
	public Resp<List<ClientExtLdpConnResp>> listExtLdpConn(@RequestParam(value = "id", required = false) Long id) {
		return Resp.ok(oauth2ClientService.listExtLdpConn(id));
	}

	/**
	 * 保存 oauth客户端
	 */
	@PostMapping("/save")
	@RamResource(action = "auth:authClientDetails:save", name = "保存oauth客户端", type = ActionType.WRITE)
	public Resp<?> save(@Validated @RequestBody OAuthClientSaveReq req) {
		return Resp.ok(oauth2ClientService.saveClient(req));
	}

	/**
	 * 更新 oauth客户端
	 */
	@PostMapping("/updateById")
	@RamResource(action = "auth:authClientDetails:update", name = "更新oauth客户端", type = ActionType.WRITE)
	public Resp<?> updateById(@Validated @RequestBody OAuthClientUpdateReq req) {
		return Resp.ok(oauth2ClientService.updateClient(req));
	}

	/**
	 * 批量删除 oauth客户端
	 */
	@RamResource(action = "auth:authClientDetails:delete", name = "删除oauth客户端", type = ActionType.WRITE)
	@DeleteMapping("/deleteBatch")
	public Resp<?> deleteBatch(@RequestParam(value = "ids") List<Long> ids) {
		return Resp.ok(oauth2ClientService.batchDeleteClient(ids));
	}

	/**
	 * 删除 oauth客户端
	 */
	@DeleteMapping("/deleteById")
	@RamResource(action = "auth:authClientDetails:delete", name = "删除oauth客户端", type = ActionType.WRITE)
	public Resp<?> delete(@RequestParam(value = "id") Long id) {
		return Resp.ok(oauth2ClientService.deleteClient(id));
	}

	@GetMapping("/refreshCache")
	@RamResource(action = "auth:authClientDetails:refreshCache", name = "刷新oauth客户端缓存", type = ActionType.WRITE)
	public Resp<?> refreshCache() {
		oauth2ClientService.clearClientCache();
		return Resp.ok();
	}

	/**
	 * 获取客户端的权限
	 * @param clientId 客户端id
	 * @return key: 服务名, value: 可访问的url集合
	 */
	@GetMapping("/listPermission")
	public Resp<Map<String, List<String>>> listPermission(@RequestParam("clientId") String clientId) {
		OAuth2Client client = oauth2ClientService.getByClientId(clientId);
		Map<String, List<String>> map = systemApi.listAssignRoleUrl(client.getRoleIds());
		return Resp.ok(map);
    }

	/**
	 * 通过角色id刷新客户端权限
	 */
	@PostMapping(value = "/refreshAuthorityByRoleIds")
	public Resp<?> refreshAuthorityByRoleId(@RequestParam("roleIds") List<Long> roleIds, @RequestParam("roleDeleted") Boolean roleDeleted) {
		oauth2ClientService.refreshClientAuthorityByRoleIds(roleIds, roleDeleted);
		return Resp.ok();
	}
}